package com.plum.core;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.plum.exception.PlumParseException;
import com.plum.model.AjaxRet;
import com.plum.realm.PlumAbstractRealm;

/**
 * PLUM初始化
 * 
 * @author lijiahong
 * @CreateDate 2018年1月24日09:35:51
 */
public class PlumInit extends Plum {
	Properties prop = new Properties();

	/**
	 * 初始化ini配置文件
	 * 
	 * @param iniPath
	 *            配置文件路径
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public void initProp(String iniPath) throws FileNotFoundException {
		InputStream in = null;
		try {
			in = new BufferedInputStream(new FileInputStream(iniPath));
			// 加载属性列表
			prop.load(in);
			in.close();
		} catch (FileNotFoundException e) {
			throw new FileNotFoundException(iniPath + "文件未找到");
		} catch (IOException e) {
			new IOException("加载或关闭" + iniPath + "发生异常");
		}
	}

	/**
	 * 解析plum.ini的roles配置
	 * 
	 * @param roles
	 * @return
	 * @throws PlumParseException
	 */
	public Set<String> parseRoles(String roles) throws PlumParseException {
		Set<String> set = new HashSet<String>();
		try {
			if (roles != null && !"".equals(roles)) {
				roles = roles.replace(PLUM_ROLES + "[", "").replace("]", "");
				String[] str = roles.split(",");
				set = new HashSet<String>(Arrays.asList(str));
			}
			return set;
		} catch (Exception e) {
			throw new PlumParseException("plum.ini中roles配置解析错误[" + roles + "]");
		}

	}

	/**
	 * 初始化配置文件中的数据
	 * 
	 * @throws PlumParseException
	 */
	public void initData() throws PlumParseException {
		Iterator<String> it = prop.stringPropertyNames().iterator();
		while (it.hasNext()) {
			String key = it.next();
			String val = prop.getProperty(key);
			if (val != null && !"".equals(val)) {
				if (key.equals(PLUM_LOGIN_URL)) {
					DEFAULT_LOGIN_URL = val;
				} else if (key.equals(PLUM_UNAUTHORIZED_URL)) {
					DEFAULT_UNAUTHORIZED_URL = val;
				} else if (key.equals(PLUM_REALM)) {
					REALM_CLASS = val;
				} else if (val.equals(PLUM_ALLOW)) {
					putAllowMap(key, val);
				} else if (val.startsWith(PLUM_ROLES)) {
					putRoleMap(key, parseRoles(val));
				}
			}
		}
		// 其他全部需要登录
		putAllowMap("/*", PLUM_DENY);
	}

	public void initRealm(String realmClass)
			throws ClassNotFoundException, IllegalAccessException, InstantiationException {
		if (realmClass != null && !"".equals(realmClass)) {
			try {
				Class<?> MyRealm = Class.forName(realmClass);
				PlumSecurity.setRealm((PlumAbstractRealm) MyRealm.newInstance());
			} catch (InstantiationException e) {
				throw new InstantiationException(realmClass + "实例化异常");
			} catch (IllegalAccessException e) {
				throw new IllegalAccessException(realmClass + "安全权限异常");
			}

		} else {
			throw new ClassNotFoundException("请配置plum.ini中的realm属性");
		}
	}
	
	/**
	 * 判断是否ajax访问
	 * @param req HttpServletRequest
	 * @return
	 */
	public boolean isAjax(HttpServletRequest req){
		boolean isAjax;
		String header = req.getHeader("X-Requested-With");
		isAjax = "XMLHttpRequest".equalsIgnoreCase(header);
		return isAjax;
	}
	
	/**
	 * 返回至ajax
	 * @param response
	 * @param ret
	 * @throws IOException
	 */
	public void AjaxReturn(HttpServletResponse response,AjaxRet ret) throws IOException{
		response.setCharacterEncoding(PLUM_DEFAULT_ENCODING);
		response.setContentType("application/json; charset="+PLUM_DEFAULT_ENCODING);
		//String jsonStr = "{\"state\":\"fail\",\"errorCode\":\"-100\",\"errorMsg\":\"当前未登录，未获得访问权限\"}";
		//AjaxRet ret = AjaxRet.fail("errorCode", "-100").set("errorMsg", "当前未登录，未获得访问权限");
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.write(ret.toString());
		} catch (IOException e) {
			throw new IOException("plum返回ajax失败");
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
}
